home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / leonid / boot.asm next >
Encoding:
Assembly Source File  |  1994-03-25  |  35.5 KB  |  1,558 lines

  1.     page    132,79
  2.     opt    rc
  3.     title    'DSP CARD 4 Bootloader'
  4.  
  5. ;***************************************************************
  6. ;* BOOT.ASM -- DSP56001 interrupt vector table and DSP CARD 4  *
  7. ;*           initialization, self cheking and communication  *
  8. ;*           service routines                    *
  9. ;*                                   *
  10. ;* Here are all DSP56001 interrupt vectors and space for       *
  11. ;* interrupt contexts and basic interrupt service routines.    *
  12. ;* Also included are initalization code, self checking and     *
  13. ;* support routines for host communication, codec control,     *
  14. ;* low level AX25 handling and transmit control.           *
  15. ;*                                   *
  16. ;* KISS protocol handling is based on article               *
  17. ;*    Chepponis, M., Karn, P.:                   *
  18. ;*    "The KISS TNC: A simple Host-to-TNC communications     *
  19. ;*     protocol",                                            *
  20. ;*    Proc. of the sixth ARRL computer networking cnf., 1988 *
  21. ;*                                   *
  22. ;* HDLC protocol handling is based on article               *
  23. ;*    Carlson, D., E.:                       *
  24. ;*    "Bit-Oriented Data Link Control Procedures",           *
  25. ;*    IEEE Trans. on Comm., Vol. 28, No. 4, April 1980       *
  26. ;*                                   *
  27. ;* CRC calculation/checking is based on article            *
  28. ;*    Morse, G.:                           *
  29. ;*    "Calculating CRCs by bits and bytes",               *
  30. ;*    BYTE Vol. 11, No. 9, September 1986               *
  31. ;*                                   *
  32. ;* Copyright (C) 1992-1994 by Alef Null. All rights reserved.  *
  33. ;* Author(s): Jarkko Vuori, OH2LNS                   *
  34. ;* Modification(s):                           *
  35. ;***************************************************************
  36.  
  37. ; DSP CARD specific parameters
  38. xtal    equ    27000000                ; XTAL frq (in MHz)
  39. topmem    equ    $1400                    ; top p memory locations where buffers and monitor routines are located
  40. rom    equ    $8000                    ; starting address of the EPROM
  41. monhigh equ    $c600                    ; part of monitor to be placed on high memory
  42. romlen    equ    32768                    ; lenght of the EPROM (in bytes)
  43.  
  44. ramx    equ    $0100                    ; external X RAM st address
  45. ramxlen equ    $2000-$0100                ; external X RAM lenght
  46. ramy    equ    $0100                    ; external Y RAM st address
  47. ramylen equ    $4000-$0100                ; external Y RAM lenght
  48. ramp    equ    $0200                    ; external P RAM st address
  49. ramplen equ    $2000-$0200                ; external P RAM lenght
  50.  
  51.  
  52. ; SCI parameters
  53. baud    equ    9600                    ; SCI baud rate
  54. buflen    equ    1024                    ; SCI input/output buffer lenght
  55.  
  56. ; Protocol parameters
  57. pgm_flash   equ 0                    ; commands
  58. chg_pgm     equ 1
  59. read_flash  equ 2
  60. load_go     equ 3
  61.  
  62. ack        equ 4                    ; responses
  63. bad_crc     equ 5
  64. no_flash    equ 6
  65. erase_err   equ 7
  66. pgm_err     equ 8
  67. no_pgm        equ 9
  68.  
  69. dataorp equ    0                    ; download space flags
  70. xory    equ    1
  71.  
  72. magicw    equ    10964                    ; special magic word to detect first time reset
  73.  
  74. ; KISS special characters
  75. fend    equ    $c0
  76. fesc    equ    $db
  77. tfend    equ    $dc
  78. tfesc    equ    $dd
  79.  
  80. ; HDLC equations
  81. flagmsk equ    $ff                    ; left justified flag mask
  82. flag    equ    %01111110                ; HDLC bit flag
  83. abrtmsk equ    $fe                    ; left justified abort mask
  84. abort    equ    %11111110                ; abort sequence
  85. fivemsk equ    $fe                    ; left justified five bit mask
  86. five    equ    %01111100                ; left justified five bit sequence
  87. poly    equ    $8408                    ; HDLC CRC polynomial (x^16 + x^12 + x^5 + 1)
  88. crcchk    equ    $f0b8                    ; special CRC checkword
  89.  
  90. ; flags
  91. rempty    equ    0                    ; SCI flags
  92. rfull    equ    1
  93. xempty    equ    2
  94. xfull    equ    3
  95. timer    equ    4                    ; timer flag
  96. scmode    equ    5                    ; serial communication mode
  97. xkissf    equ    6                    ; put KISS frame begin
  98. ztstflg equ    7                    ; HDLC xmitter status flags
  99. zinsflg equ    8
  100. hunt    equ    9                    ; HDLC receiver status flags
  101. firstb    equ    10
  102. scndb    equ    11
  103. pwrup    equ    12                    ; set if power-up reset
  104. carrier equ    13                    ; carrier on/off
  105. givedat equ    14                    ; data output gate
  106.  
  107.  
  108. ; macro for green LED handling
  109. copled    macro    mode
  110.     b\mode    #14,x:m_pbd
  111.     endm
  112.  
  113. ; macro for red LED handling
  114. cmdled    macro    mode
  115.     b\mode    #13,x:m_pbd
  116.     endm
  117.  
  118. ; macro for immediate move
  119. movi    macro    data,dest
  120.     move            data,a1
  121.     move            a1,dest
  122.     endm
  123.  
  124. ; macro for entering interrupt service routine
  125. ; stores x0,x1 and a registers
  126. enter    macro    contex
  127.     move            x,l:<contex+0
  128.     move            a10,l:<contex+1
  129.     endm
  130.  
  131. ; macro for leaving interrupt service routine
  132. ; restores x0,x1 and a registers
  133. leave    macro    contex
  134.     move            l:<contex+0,x
  135.     move            l:<contex+1,a10
  136.     rti
  137.     endm
  138.  
  139. ; CRC calculation routine
  140. ; data in the LSB of a
  141. crc    macro    rem
  142.     move            #>1,x0
  143.     and    x0,a        rem,x0
  144.     eor    x0,a
  145.     lsr    a        #>poly,x0
  146.     jcc    _crc1
  147.     eor    x0,a
  148. _crc1    move            a1,rem
  149.     endm
  150.  
  151. ; byte CRC calculation routine
  152. ; byte in x0, result in x:<crcrem
  153. crcbyte macro
  154.     move    x0,b1
  155.     move            #>$000001,x1
  156.     move            #>poly,y1
  157.     do    #8,_crc2
  158.  
  159.     move    b1,a1                    ; first LSB to remainder
  160.     and    x1,a        x:<crcrem,y0
  161.     eor    y0,a
  162.  
  163.     lsr    a                    ; XOR if needed
  164.     jcc    _crc1
  165.     eor    y1,a
  166. _crc1    lsr    b        a1,x:<crcrem
  167. _crc2
  168.     endm
  169.  
  170. ; macro for subroutines to read word from ROM and load one ROM image
  171. romhdlr macro    rdromb,rdromw,romload
  172. ; read one byte from the boot ROM to x0
  173. rdromb    movep            #$00f0,x:m_bcr        ; slow EPROM on P bank
  174.     move            p:(r1)+,x0
  175.     move            #$0000ff,b1         ; mask unused databits off
  176.     and    x0,b
  177.     move    b1,x0
  178.     movep            #$0000,x:m_bcr        ; no more slow EPROM reads
  179.     rts
  180.  
  181. ; read one word from the boot ROM to a1
  182. rdromw    jsr    rdromb                      ; LS byte
  183.     move            x0,y:<tmp
  184.     jsr    rdromb                      ; MS byte
  185.     move            #>@cvi(@pow(2,8-1)),x1
  186.     mpy    x0,x1,a     y:<tmp,x0
  187.     move    a0,a1
  188.     or    x0,a
  189.     rts
  190.  
  191. ; load memory blocks from r1
  192. romload jsr    rdromb                      ; packet id
  193.     move            x0,y:<mspace
  194.  
  195.     jsr    rdromw                    ; address
  196.     move    a1,r0
  197.  
  198.     jsr    rdromw                    ; len
  199.     move    a1,n0
  200.  
  201.     jeq    _loaded
  202.     do    n0,_contld                ; fetch data
  203.     jsr    rdromb
  204.     move            x0,y:<tmp
  205.     jsr    rdromb
  206.     move            #>@cvi(@pow(2,8-1)),x1
  207.     mpy    x0,x1,a     y:<tmp,x1
  208.     move    a0,a1
  209.     or    x1,a
  210.     move            a1,y:<tmp
  211.     jsr    rdromb
  212.     move            #>@cvi(@pow(2,16-1)),x1
  213.     mpy    x0,x1,a     y:<tmp,x1
  214.     move    a0,a1
  215.     or    x1,a
  216.     jclr    #dataorp,y:mspace,_d
  217.     move            a1,p:(r0)+            ; put to P space
  218.     jmp    _a
  219. _d    jclr    #xory,y:mspace,_x
  220.     move            a1,y:(r0)+            ; put to Y space
  221.     jmp    _a
  222. _x    move            a1,x:(r0)+            ; put to X space
  223. _a    nop
  224. _contld
  225.     jmp    romload
  226. _loaded rts
  227.     endm
  228.  
  229.  
  230.     nolist
  231.     include 'ioequlc'
  232.     include 'intequlc'
  233.     list
  234.  
  235. ; Reset vector
  236.     org    p:i_reset
  237.     jmp    boot
  238.  
  239. ; Stack error interrupt
  240.     org    p:i_stack
  241.     jmp    shdown
  242.  
  243. ; Trace interrupt
  244.     org    p:i_trace
  245.     jmp    shdown
  246.  
  247. ; SWI
  248.     org    p:i_swi
  249.     jmp    shdown
  250.  
  251. ; IRQA
  252.     org    p:i_irqa
  253.     jmp    shdown
  254.  
  255. ; IRQB
  256.     org    p:i_irqb
  257.     jmp    shdown
  258.  
  259. ; SSI transmitter interrupt
  260. ;(because syncronous mode, we can use the same interrupt for both reading and writing)
  261.     org    p:i_ssitd
  262.     movep            y:(r7)+,x:m_tx
  263.     movep            x:m_rx,x:(r7)
  264.  
  265. ; SSI transmitter interrupt with errors
  266.     org    p:i_ssitde
  267.     movep            x:m_sr,x:m_tx        ; clear TUE
  268.  
  269. ; SCI receive interrupt
  270.     org    p:i_scird
  271.     jsr    sci_rec
  272.  
  273. ; SCI receive interrupt with errors
  274.     org    p:i_scirde
  275.     jsr    sci_rec
  276.  
  277. ; SCI transmitter interrupt
  278.     org    p:i_scitd
  279.     jsr    sci_xmt
  280.  
  281. ; SCI timer interrupt
  282.     org    p:i_scitm
  283.     jsr    sci_tim
  284.  
  285. ; Monitor routine jump table (here because host port is not used)
  286.     org    p:i_hstrd
  287.     jmp    opensci
  288.     jmp    putc
  289.     jmp    getc
  290.     jmp    tstc
  291.     jmp    endc
  292.     jmp    rejc
  293.     jmp    putbit
  294.     jmp    getbit
  295.     jmp    opencd
  296.     jmp    closecd
  297.     jmp    stimer
  298.     jmp    putio
  299.     jmp    caron
  300.     jmp    caroff
  301.  
  302. ; System error shutdown
  303. shdown    stop
  304.  
  305. ; Illegal instruction interrupt
  306.     org    p:$003e
  307.     jmp    >shdown
  308.  
  309. ;****************************
  310. ;*   Start of the program   *
  311. ;****************************
  312. ; no wait states on external memory
  313. boot    movep            #$0000,x:m_bcr
  314.  
  315. ; initialize SCI
  316.     movep            #$2b02,x:m_scr        ; 8,n,1
  317.     movep            #(xtal+2*16*baud)/(2*2*16*baud)-1,x:m_sccr      ; round baud
  318.  
  319. ; initialize port B
  320.     movep            #$0000,x:m_pbc        ; port B as general purpose port
  321.     movep            #$60ff,x:m_pbddr        ; PB0-PB7,PB13 and PB14 as outputs
  322.     movep            #$0000,x:m_pbd
  323.  
  324. ; initialize port C
  325.     movep            #$0003,x:m_pcc        ; TXD,RXD
  326.     movep            #$001c,x:m_pcddr        ; SCLK,SC0,SC1 as output
  327.     movep            #$0008,x:m_pcd        ; PDN up
  328.  
  329. ; initialize data structures
  330.     move            #outbuf,a1            ; SCI queue handling
  331.     move            a1,x:<xhead
  332.     move            a1,x:<xtail
  333.     move            #inbuf,a1
  334.     move            a1,x:<rhead
  335.     move            a1,x:<rtail
  336.     move            #buflen-1,m3
  337.  
  338.     move            #@cvi(0.5*baud),n3        ; SCI timer system
  339.     clr    a
  340.     move            a,y:<timchg
  341.     move            a,y:<timcnt
  342.  
  343.     move            #<(1<<rempty)|(1<<xempty),a1
  344.     move            a1,y:<flags         ; buffer empty at first
  345.  
  346.     move            #wakeup,a1
  347.     move            a1,x:<seqptr
  348.  
  349. ; check if power-up reset
  350.     move            y:<pgmptr,a         ; if active program location
  351.     rep    #4-1                    ; contains a special magic pattern
  352.     asr    a                    ; this is not a power-up reset
  353.     asr    a        #>magicw,x0
  354.     eor    x0,a
  355.     jeq    <chkok
  356.     bset    #pwrup,y:<flags
  357.  
  358. ; hit watchdog (because system testing will take a while)
  359.     copled    chg
  360.  
  361. ; check the system (ROM)
  362.     move            #rom,r1            ; calculate ROM's CRC sum
  363.     move            #$00ffff,a1
  364.     move            a1,x:<crcrem
  365.  
  366.     move            #romlen,r0
  367.     do    r0,check1
  368.     jsr    <rdb
  369.     jsr    <crcb
  370.     nop
  371.  
  372. check1    move            #>crcchk,x0         ; check with special checkword
  373.     move            x:<crcrem,a
  374.     cmp    x0,a
  375.     jne    <rombad
  376.  
  377. ; check the system (RAM)
  378.     move            #$00ffff,a1         ; initialize test pattern generator
  379.     move            a1,x:<crcrem
  380.  
  381.     move            #ramx,r1            ; write test pattern to X ram
  382.     move            #ramxlen,r0
  383.     do    r0,check2a
  384.     move            #0,x0
  385.     jsr    <tstpat
  386.     move            a1,x:(r1)+
  387. check2a
  388.  
  389.     move            #ramy,r1            ; write test pattern to Y ram
  390.     move            #ramylen,r0
  391.     do    r0,check2b
  392.     move            #0,x0
  393.     jsr    <tstpat
  394.     move            a1,y:(r1)+
  395. check2b
  396.  
  397.     move            #ramp,r1            ; write test pattern to P ram
  398.     move            #ramplen,r0
  399.     do    r0,check2c
  400.     move            #0,x0
  401.     jsr    <tstpat
  402.     move            a1,p:(r1)+
  403. check2c
  404.  
  405.     move            #$00ffff,a1         ; initialize test pattern generator
  406.     move            a1,x:<crcrem
  407.  
  408.     move            #ramx,r1            ; test X ram
  409.     move            #ramxlen,r0
  410.     move            #0,x0
  411.     do    r0,check3a
  412.     jsr    <tstpat
  413.     move            x:(r1)+,x0
  414.     eor    x0,a        #0,x0
  415.     jne    <rambad
  416.     nop
  417. check3a
  418.  
  419.     move            #ramy,r1            ; test Y ram
  420.     move            #ramylen,r0
  421.     move            #0,x0
  422.     do    r0,check3b
  423.     jsr    <tstpat
  424.     move            y:(r1)+,x0
  425.     eor    x0,a        #0,x0
  426.     jne    <rambad
  427.     nop
  428. check3b
  429.  
  430.     move            #ramp,r1            ; test P ram
  431.     move            #ramplen,r0
  432.     move            #0,x0
  433.     do    r0,check3c
  434.     jsr    <tstpat
  435.     move            p:(r1)+,x0
  436.     eor    x0,a        #0,x0
  437.     jne    <rambad
  438.     nop
  439. check3c
  440.  
  441. ; read the remaining monitor to the upper memory
  442. chkok    move            #monhigh,r1
  443.     jsr    <memload
  444.  
  445. ; start interrupts
  446.     movep            #$b000,x:m_ipr        ; SSI=IPL2, SCI=IPL1
  447.     andi    #$fc,mr                 ; unmask interrupts
  448.  
  449. ; wait 1 s for the (possible) command
  450.     cmdled    set
  451.     move            #>ack,x0            ; tell to host that we managed to get out from the reset
  452.     jsr    putc
  453.  
  454.     move            #>@cvi(1.0*baud),x0     ; set timer
  455.     jsr    stimer
  456. _wchr    wait
  457.     jsr    getc                    ; wait for chr of timer
  458.     jcc    <cmdok
  459.     jset    #timer,y:<flags,_wchr
  460.  
  461. ldpgm    cmdled    clr                    ; no complete command, turn cmd led off
  462.     move            y:<pgmptr,a
  463.     jset    #pwrup,y:<flags,firstrs
  464.  
  465. _nopgm    move            #>$00000f,x0        ; no, calculate next pgm slot number
  466.     and    x0,a        #>1,x0
  467.     add    x0,a        #>16,x1            ; robin round if last pgm slot number
  468.     cmp    x1,a
  469.     tge    x0,a
  470.     move            a1,y:<pgmptr
  471.     jsr    ldadr
  472.     move            y:<pgmptr,a
  473.     jeq    <_nopgm
  474. ldnextp move            #>magicw<<4,b        ; active pgm slot found, store slot number
  475.     move    a1,x0
  476.     or    x0,b
  477.     move            b1,y:<pgmptr
  478.     jmp    lromg                    ; and load image from ROM and jump to it
  479.  
  480. firstrs move            #rom+2,r1            ; first reset, check if there are autoboot programs
  481.     jsr    <rdw
  482.     jne    <ldnextp
  483.  
  484. _idling wait                        ; nothing to do (no command given, no program to load from ROM)
  485.     jmp    <_idling
  486.  
  487. ; command read, search command
  488. cmdok    move            #>load_go,a
  489.     cmp    x0,a
  490.     jeq    lg
  491.  
  492.     jmp    <ldpgm
  493.  
  494.  
  495. ; temporary utility routines in internal memory
  496.     romhdlr rdb,rdw,memload
  497.  
  498. crcb    crcbyte
  499.     rts
  500.  
  501. ; pseudonoise RAM test pattern generator (pattern in a)
  502. tstpat    jsr    <crcb
  503.     move            x:<crcrem,a
  504.     rep    #8-1
  505.     lsl    a
  506.     lsl    a        x:<crcrem,x1
  507.     eor    x1,a
  508.     rts
  509.  
  510. ; 100 ms software delay
  511. dly100    do    #@cvi(@sqt(xtal/2.0/10.0)),_romb2
  512.     do    #@cvi(@sqt(xtal/2.0/10.0)),_romb1
  513.     nop
  514. _romb1    nop
  515. _romb2    rts
  516.  
  517. ; show that ROM has failed crc check (red and green led blinks at 10 Hz)
  518. rombad    jsr    <dly100
  519.     copled    chg
  520.     cmdled    chg
  521.     jmp    <rombad
  522.  
  523. ; show that RAM has failed check (greed led blinks at 10 Hz, red led blinks at 5 Hz)
  524. rambad    jsr    <dly100
  525.     copled    chg
  526.     cmdled    chg
  527.     jsr    <dly100
  528.     copled    chg
  529.     jmp    <rambad
  530.  
  531.  
  532.  
  533. ;**********************************************************
  534. ;* The following code will be placed to top p-memory bank *
  535. ;**********************************************************
  536.  
  537.     org    p:topmem
  538.  
  539. ;****************************
  540. ;*    SCI timer interrupt   *
  541. ;****************************
  542. sci_tim enter    scidata                 ; only a1,a0,x1,x0 are saved
  543.  
  544. ; increment timer
  545.     move            #-1,m3            ; yes, set next time
  546.     move            y:<timcnt,r3
  547.  
  548. ; check if destination time reached
  549.     move            y:<timval,a1
  550.     move            r3,x0
  551.     eor    x0,a        (r3)+
  552.     jne    _scit1
  553.     bclr    #timer,y:<flags             ; yes, clear flag bit
  554.  
  555. ; check if watch-dog interval reached
  556. _scit1    move            y:<timchg,a1
  557.     eor    x0,a        r3,y:<timcnt
  558.     jne    scite
  559.     copled    chg
  560.     move            (r3)+n3
  561.     nop
  562.     move            r3,y:<timchg
  563.  
  564. scite    jsr    pertick                 ; xmit control module timer
  565.     move            #buflen-1,m3
  566.     leave    scidata
  567.  
  568.  
  569.  
  570. ;****************************
  571. ;*    SCI xmit interrupt    *
  572. ;****************************
  573. sci_xmt enter    scidata                 ; only a1,a0,x1,x0 are saved
  574.  
  575.     move            x:<xtail,r3
  576.     move            x:<xhead,x0
  577.     movep            p:(r3)+,x:m_stxl
  578.     move            r3,x:<xtail
  579.  
  580.     bclr    #xfull,y:<flags             ; don't bother to check buffer state if it is full
  581.     jcs    scixe
  582.  
  583. ; check if buffer empty
  584.     move    r3,a1
  585.     eor    x0,a
  586.     jne    scixe
  587.  
  588. ; yes, shut down xmitter
  589.     bset    #xempty,y:<flags
  590.     bclr    #m_tie,x:m_scr
  591.  
  592. scixe    leave    scidata
  593.  
  594.  
  595. ;****************************
  596. ;*   SCI receive interrupt  *
  597. ;****************************
  598. wakeup    dc    $12,$b9,$b0,$a1
  599. sci_rec enter    scidata                 ; only a1,a0,x1,x0 are saved
  600.  
  601.     movep            x:m_ssr,x1            ; clear SCI errors
  602.  
  603. ; first check for special wake-up sequence
  604.     move            x:<seqptr,r3
  605.     movep            x:m_srxl,x1         ; read byte to x1
  606.     move            p:(r3)+,a1
  607.     eor    x1,a        #>wakeup+4,x0
  608.     jeq    scir1
  609.     move            #wakeup,r3
  610.     jmp    scir2
  611. scir1    move            r3,a1
  612.     eor    x0,a
  613.     jne    scir2
  614.  
  615. ; wake-up sequence detected (boot the system up)
  616.     stop                        ; watchdog will give reset pulse
  617.  
  618. ; no wake-up sequence detected, continue searching
  619. scir2    move            r3,x:<seqptr
  620.  
  621. ; then check that there are room left in the buffer
  622.     jset    #rfull,y:<flags,scire
  623.  
  624. ; yes, determine in which mode we are (normal, KISS mode)
  625.     jset    #scmode,y:<flags,scir3
  626.  
  627. ; * normal mode, put data to buffer
  628.     move            x:<rhead,r3
  629.     bclr    #rempty,y:<flags
  630.     move            x1,p:(r3)+
  631.     move            r3,x:<rhead
  632.  
  633. ; check buffer full condition
  634.     move            r3,a1
  635.     move            x:<rtail,x0
  636.     eor    x0,a
  637.     jne    scire
  638.     bset    #rfull,y:<flags
  639.  
  640.     jmp    scire
  641.  
  642. ; * KISS protocol mode, read received character
  643. scir3    move            x:<getkst,r3
  644.     move            #fend,a1
  645.     jmp    (r3)                    ; determine what to do for it
  646.  
  647. ; --- State 0, waiting for FEND
  648. str0    eor    x1,a        #>str1,x0
  649.     jne    scire                    ; we didn't see FEND, keep looking
  650.     move    x0,x:<getkst                ; FEND found, change state
  651.     jmp    scire
  652.  
  653. ; --- State 1, we have seen FEND, look for the command byte
  654. str1    eor    x1,a        #>str2,x0
  655.     jeq    scire                    ; just another FEND, keep looking for cmd
  656. ; analyze command byte
  657.     move            #0,a1
  658.     eor    x1,a        x1,x:<kisscmd
  659.     jeq    str1b                    ; cmd 0, data will follow
  660. ; store cmd and change state
  661. str1a    move            #str4,a1
  662.     move            a1,x:<getkst
  663.     jmp    scire
  664. ; start a new frame
  665. str1b    move            x0,x:<getkst
  666.     move            x:<rhead,a1         ; get current rhead
  667.     move            a1,x:<rnhead
  668.     jmp    scire
  669.  
  670. ; --- State 2, data to follow
  671. str2    eor    x1,a                    ; check if end of frame
  672.     jeq    strend
  673.     move            #fesc,a1
  674.     eor    x1,a                    ; check if escape
  675.     jne    store
  676. ; escape character found
  677.     move            #str3,a1            ; enter FESC found state
  678.     move            a1,x:<getkst
  679.     jmp    scire
  680. ; end of frame, store negative value
  681. strend    move            #-1,x1
  682.     jmp    store
  683.  
  684. ; --- State 3, saw FESC, expecting TFESC or TFEND
  685. str3    move            #tfesc,a1            ; check if TFESC
  686.     eor    x1,a
  687.     jeq    str3esc
  688.     move            #tfend,a1
  689.     eor    x1,a                    ; check if TFEND
  690.     jeq    str3end
  691.     move            #str2,a1
  692.     move            a1,x:<getkst        ; something wrong has happened,
  693.     jmp    scire                    ; go back to the data receiving mode
  694. ; we have seen TFESC after an FESC, write an FESC
  695. str3esc move            #str2,a1
  696.     move            a1,x:<getkst
  697.     move            #>fesc,x1
  698.     jmp    store
  699. ; we have seen TFEND after an FESC, write an FEND
  700. str3end move            #str2,a1
  701.     move            a1,x:<getkst
  702.     move            #>fend,x1
  703.  
  704. ; store the character to the queue
  705. store    move            x:<rnhead,r3
  706.     move            x:<rtail,x0
  707.     move            x1,p:(r3)+
  708.     move    r3,a1                    ; check buffer full
  709.     eor    x0,a        r3,x:<rnhead
  710.     jeq    scr_st0                 ; queue full, discard current frame
  711. ; check if end of frame
  712.     move            #-1,a1
  713.     eor    x1,a        x:<rnhead,x1
  714.     jne    scire
  715.  
  716.     move            x1,x:<rhead         ; yes, reset real buffer write pointer
  717.     bclr    #rempty,y:<flags
  718.     jsr    frmrec                    ; inform xmit control module
  719.     jmp            scr_st0
  720.  
  721. ; --- State 4, get command data
  722. str4    move            a0,y:<tmp            ; backup a0
  723.     move            x:<kisscmd,a        ; check if local parameter
  724.     move            #>kisses,x0
  725.     cmp    x0,a        #>kisspar-1,x0
  726.     jgt    str4a
  727.  
  728.     add    x0,a        #>baud/100,x0
  729.     mpy    x0,x1,a     a,r3            ; yes, time scale parameter
  730.     asr    a                    ; interger multiply correction
  731.     move            a0,p:(r3)            ; product in low order word
  732.     jmp    str4b
  733.  
  734. str4a    move            y:<kisssub,r3        ; no, give it to the user application
  735.     move            x:<kisscmd,a
  736.     jsr    (r3)                    ; a1 - cmd, x1 - data
  737. str4b    move            y:<tmp,a0
  738.  
  739. ; go back to FEND hunt state
  740. scr_st0 move            #str0,a1
  741.     move            a1,x:<getkst
  742.  
  743. scire    leave    scidata
  744.  
  745.  
  746. ;**************************
  747. ;* LOAD FROM HOST AND GO  *
  748. ;**************************
  749. lg    move            #>ack,x0            ; tell to host that command was accepted
  750.     jsr    putc
  751.  
  752. lghunt    move            #$00ffff,a1         ; try to find beginning of the frame
  753.     move            a1,x:<crcrem
  754.     jsr    rdbyte
  755.     move            #>flag,a
  756.     cmp    x0,a
  757.     jne    lghunt
  758.  
  759.     jsr    rdbyte                    ; packet id
  760.     move            x0,y:<mspace
  761.  
  762.     jsr    rdword                    ; address
  763.     move    a1,r0
  764.  
  765.     jsr    rdword                    ; len
  766.     move    a1,n0
  767.  
  768.     jeq    alldata
  769.     do    n0,alldata                ; fetch data
  770.     jsr    rdbyte
  771.     move            #>@cvi(@pow(2,16-1)),x1
  772.     mpy    x0,x1,a
  773.     move            a0,y:<tmp
  774.     jsr    rdbyte
  775.     move            #>@cvi(@pow(2,8-1)),x1
  776.     mpy    x0,x1,a     y:<tmp,x1
  777.     move    a0,a1
  778.     or    x1,a
  779.     move            a1,y:<tmp
  780.     jsr    rdbyte
  781.     move            y:<tmp,a
  782.     or    x0,a
  783.     jclr    #dataorp,y:mspace,_d
  784.     move            a1,p:(r0)+            ; put to P space
  785.     jmp    _a
  786. _d    jclr    #xory,y:mspace,_x
  787.     move            a1,y:(r0)+            ; put to Y space
  788.     jmp    _a
  789. _x    move            a1,x:(r0)+            ; put to X space
  790. _a    nop
  791. alldata
  792.  
  793.     jsr    rdbyte                    ; CRC
  794.     jsr    rdbyte
  795.     move            #>crcchk,x0
  796.     move            x:<crcrem,a
  797.     cmp    x0,a        #>ack,x0
  798.     jeq    _crcok
  799.     move            #>bad_crc,x0        ; crc bad, ignore frame
  800.     jsr    putc
  801.     jmp    lghunt
  802.  
  803. _crcok    jsr    putc                    ; crc ok, if len=0 then jump to the user code
  804.     move    n0,a
  805.     tst    a
  806.     jne    lghunt
  807.     cmdled    clr
  808.     jmp    <boot
  809.  
  810.  
  811. ;********************
  812. ;* LOAD ROM AND GO  *
  813. ;********************
  814. ; program number is in a1 register
  815. lromg    jsr    ldadr
  816.     move    a1,r1
  817.     jsr    romload                 ; then load the program
  818.     jmp    <boot                    ; and finally jump to it
  819.  
  820.  
  821. ;****************************
  822. ;*     Open Serial line     *
  823. ;****************************
  824. ; flushes all buffers and set the desired communication speed
  825. ;   a - kiss command routine address (zero if not is kiss mode)
  826. ;   b - xmit on/off routine address
  827. opensci move            a,y:<kisssub
  828.     bclr    #scmode,y:<flags
  829.     tst    a        #str0,a1
  830.     jeq    opensce
  831.  
  832. ; KISS mode, initialize handlers
  833.     move            b1,y:<xmitsub        ; store given addresses
  834.     move            a1,x:<getkst
  835.     move            #(1<<xoff),b1
  836.     clr    b        b1,x:<pstate        ; and initialize xmit control module
  837.     move            b1,y:<pertim
  838.  
  839.     bset    #scmode,y:<flags
  840.     bclr    #xkissf,y:<flags
  841.  
  842.     movi    #xstD,y:<xstate             ; initialize coder
  843.     movi    #flag,y:<xdata
  844.     movi    #$0,y:<x5bit
  845.     movi    #0,y:<xbit
  846.     bclr    #ztstflg,y:<flags
  847.     bclr    #zinsflg,y:<flags
  848.  
  849.     movi    #0,x:<rdata                ; initialize decoder
  850.     movi    #$0,x:<rflag
  851.     bset    #hunt,y:<flags
  852.     bset    #firstb,y:<flags
  853.     bset    #scndb,y:<flags
  854.  
  855. opensce rts
  856.  
  857.  
  858. ;****************************
  859. ;*  Put character to queue  *
  860. ;****************************
  861. ; byte in x0
  862. ; returns  Z if buffer full
  863. ;      NZ otherwise
  864. putc    ori    #$02,mr                 ; disable interrupts
  865.     nop
  866.     nop
  867.     jset    #scmode,y:<flags,putkiss
  868.  
  869. ; * normal mode
  870.     move            x:<xtail,x1
  871.     move            x:<xhead,a1
  872.     move            a1,r3
  873.  
  874. ; xmitter was running, check if there are free space left
  875.     bclr    #xempty,y:<flags            ; if buffer empty, sure there are free space left
  876.     jcs    putc1
  877.     eor    x1,a                    ; if read ptr <> write ptr there are also free space left
  878.     jne    putc2
  879.  
  880. ; buffer full state reached (ignore given data)
  881.     bset    #xfull,y:<flags
  882.     jmp    putce
  883.  
  884. ; there was free space left, write character to the buffer
  885. putc1    bset    #m_tie,x:m_scr                ; start xmitter interrupts
  886. putc2    move            x0,p:(r3)+
  887.     move            r3,x:<xhead
  888.     jmp    putce
  889.  
  890.  
  891. ; * KISS mode, check if start of new KISS frame
  892. putkiss jset    #xkissf,y:<flags,putk1
  893.  
  894. ; yes, send KISS preamble
  895.     bset    #xkissf,y:<flags
  896.     move            x:<xhead,r3
  897.     move            r3,x:<xnhead
  898.  
  899.     move            #fend,a1
  900.     move            a1,p:(r3)+
  901.     move            #0,a1
  902.     move            a1,p:(r3)+
  903.  
  904.     move            r3,x:<xnhead
  905.  
  906. ; no, send pure data only
  907. putk1    move            x:<xnhead,r3
  908.  
  909.     move            #fesc,a1            ; check if FESC
  910.     eor    x0,a        #tfesc,b1
  911.     jeq    putkspe
  912.  
  913.     move            #fend,a1            ; check if FEND
  914.     eor    x0,a        #tfend,b1
  915.     jne    putke1
  916.  
  917. ; special character, enter escaped special character
  918. putkspe move            #>fesc,x0
  919.     move            x0,p:(r3)+
  920.     move    b1,x0
  921.  
  922. putke1    move            x0,p:(r3)+
  923.     move            r3,x:<xnhead
  924.  
  925. putce    andi    #$fc,mr
  926.     rts
  927.  
  928.  
  929. ;****************************
  930. ;* End current KISS frame   *
  931. ;****************************
  932. endc    ori    #$02,mr                 ; disable interrupts
  933.     nop
  934.     nop
  935.     nop
  936.     bclr    #xkissf,y:<flags
  937.  
  938.     move            x:<xnhead,r3        ; write last fend
  939.     move            #>fend,x0
  940.     move            x0,p:(r3)+
  941.     move            r3,x:<xhead
  942.  
  943.     jclr    #xempty,y:<flags,ekisse         ; check for idling xmitter
  944.     bset    #m_tie,x:m_scr
  945.  
  946. ekisse    andi    #$fc,mr
  947.     rts
  948.  
  949.  
  950. ;****************************
  951. ;* Reject current KISS frame*
  952. ;****************************
  953. rejc    bclr    #xkissf,y:<flags
  954.     rts
  955.  
  956.  
  957. ;****************************
  958. ;* Get character from queue *
  959. ;****************************
  960. ; byte in x0
  961. ; returns  C if no data available
  962. ;      NC if data available
  963. getc    ori    #$02,mr                 ; disable interrupts
  964.     nop
  965.     nop
  966.     nop
  967.     nop
  968.     move            x:<rtail,r3
  969.  
  970. ; check if there are data available
  971.     btst    #rempty,y:<flags
  972.     jcs    getce
  973.  
  974. ; yes, take it from the queue
  975.     bclr    #rfull,y:<flags
  976.     move            p:(r3)+,x0
  977.     move            r3,x:<rtail
  978.  
  979. ; check if buffer gets empty
  980.     move            x:<rhead,a
  981.     move            r3,x1
  982.     cmp    x1,a
  983.     andi    #$fe,ccr                ; NC
  984.     jne    getce
  985.  
  986. ; yes, set empty flag
  987.     bset    #rempty,y:<flags
  988.  
  989. getce    andi    #$fc,mr
  990.     rts
  991.  
  992.  
  993. ;****************************
  994. ;* Test if chrs available   *
  995. ;****************************
  996. ; returns  C if no data available
  997. ;      NC if data available
  998. tstc    btst    #rempty,y:<flags
  999.     rts
  1000.  
  1001.  
  1002. ;****************************
  1003. ;*      Get a bit        *
  1004. ;****************************
  1005. ; returns next bit to be sent in C
  1006. ; returns Z if this is an end of the transmission
  1007. ; Note! Interrupts are disabled if end of transmission detected
  1008.  
  1009. ; check if we are allowed to send data
  1010. getbit    jclr    #givedat,y:<flags,xstD2
  1011.  
  1012. ; check if we must insert a zero
  1013.     bclr    #zinsflg,y:<flags
  1014.     jcs    getins
  1015.  
  1016. ; check if there are bits left
  1017.     move            y:<xbit,a
  1018.     tst    a        y:<xstate,r0
  1019.     nop
  1020.     jeq    (r0)
  1021.  
  1022. ; five bit sequence detection logic
  1023. getsft0 jclr    #ztstflg,y:<flags,getsft1      ; check if logic enabled
  1024.     move            y:<xdata,a
  1025.     lsr    a
  1026.     move            y:<x5bit,a
  1027.     ror    a        #>$f80000,x0
  1028.     and    x0,a
  1029.     cmp    x0,a        a1,y:<x5bit
  1030.     jne    getsft1
  1031.  
  1032. ; 11111 detected, insert zero
  1033.     bset    #zinsflg,y:<flags
  1034.  
  1035. ; calculate CRC
  1036. getsft1 move            y:<xdata,a
  1037.     crc    y:<xcrcrem
  1038.  
  1039. ; shift data out (LSB first) and decrement bit counter
  1040.     move            y:<xbit,r0
  1041.     move            y:<xdata,a
  1042.     lsr    a        (r0)-
  1043.     move            r0,y:<xbit
  1044.     move            a1,y:<xdata
  1045.     andi    #$fb,ccr                ; NZ
  1046.     rts
  1047.  
  1048. ; insert zero bit
  1049. getins    clr    a                    ; reset five bit counter
  1050.     move            a1,y:<x5bit
  1051.     andi    #$fa,ccr                ; NC NZ
  1052.     rts
  1053.  
  1054.  
  1055. ; --- A, after a begin flag
  1056. xstA
  1057. ; set up data xmission
  1058.     movi    #xstB,y:<xstate
  1059.     movi    #$00ffff,y:<xcrcrem            ; init CRC generator
  1060.     bset    #ztstflg,y:<flags            ; enable 11111 checker
  1061.  
  1062. ; --- B, after data byte sent
  1063. xstB    movi    #8,y:<xbit                ; init bit counter for the next byte
  1064.     jsr    getc                    ; fetch next byte
  1065.     move    x0,y:<xdata
  1066.     move    x0,a
  1067.     tst    a
  1068.     jpl    getsft0
  1069.  
  1070. ; last databyte sent, send CRC
  1071.     movi    #xstC,y:<xstate
  1072.     movi    #16,y:<xbit
  1073.     move            y:<xcrcrem,a
  1074.     not    a
  1075.     move            a1,y:<xdata
  1076.     jmp    getsft0
  1077.  
  1078. ; --- C, after CRC sent
  1079. xstC    movi    #xstD,y:<xstate
  1080.     movi    #flag,y:<xdata
  1081.     movi    #8,y:<xbit
  1082.     bclr    #ztstflg,y:<flags            ; disable 11111 checker
  1083.     jmp    getsft0
  1084.  
  1085. ; --- D, after the last flag sent
  1086. xstD    jsr    tstc
  1087.     jcs    xstD1
  1088.  
  1089. ; new data to send, start a new frame
  1090.     movi    #xstA,y:<xstate
  1091.     movi    #flag,y:<xdata
  1092.     movi    #8,y:<xbit
  1093.     jmp    getsft0
  1094.     rts
  1095.  
  1096. ; no new data, return with Z
  1097. xstD1    jsr    rdempty                 ; inform xmit control module
  1098. xstD2    ori    #$04,ccr
  1099.     rts
  1100.  
  1101.  
  1102. ;****************************
  1103. ;*      Put a bit        *
  1104. ;****************************
  1105. ; put next bit in C to the host transmit queue
  1106. putbit    move            x:<rflag,a
  1107.     ror    a        #abrtmsk,b
  1108.     move            a1,x:<rflag
  1109.     move            a1,x0
  1110.  
  1111. ; check if abort sequence detected
  1112.     and    x0,b        #abort,y0
  1113.     eor    y0,b
  1114.     jeq    putb4
  1115.  
  1116. ; check if flag detected
  1117.     move            #flagmsk,b
  1118.     and    x0,b        #flag,y0
  1119.     eor    y0,b        #fivemsk,a
  1120.     jeq    putb3                    ; yes, special handling
  1121.  
  1122. ; check if 11111 sequence detected
  1123.     and    x0,a        #five,y0
  1124.     eor    y0,a        x0,b
  1125.     jeq    putb2                    ; yes, ignore this bit
  1126.  
  1127. ; no special sequence detected, shift data normally
  1128.     jset    #hunt,y:<flags,putb2
  1129.     lsl    b        x:<rdata,a
  1130.     ror    a        #>@pow(2,-15),x1
  1131.     move            a1,x:<rdata
  1132.     move            a1,x0
  1133.  
  1134. ; calculate CRC
  1135.     mpy    x0,x1,a     #>1,x1            ; shift to right 15 bits
  1136.     crc    x:<rcrcrem
  1137.  
  1138. ; decrement the bit counter
  1139.     move            x:<rbit,a
  1140.     sub    x1,a        #8,b1
  1141.     move            a1,x:<rbit
  1142.     jne    putb2
  1143.  
  1144. ; 8 bit shifted, init bit counter again
  1145.     move            b1,x:<rbit
  1146.     bclr    #firstb,y:<flags
  1147.     jcc    putb1
  1148.  
  1149. ; first byte, init CRC checker
  1150.     move            #$00ffff,a1
  1151.     move            a1,x:<rcrcrem
  1152.     rts
  1153.  
  1154. ; data bytes, put it to the queue
  1155. putb1    bclr    #scndb,y:<flags
  1156.     jcs    putb2
  1157.     move            x:<rdata,a
  1158.     move            #>$ff,x0
  1159.     and    x0,a
  1160.     move            a1,x0
  1161.     jsr    putc
  1162.  
  1163. ; discard the previous bit
  1164. putb2    rts
  1165.  
  1166. ; flag detected
  1167. putb3    bclr    #hunt,y:<flags
  1168.     movi    #8,x:<rbit
  1169.     bset    #firstb,y:<flags
  1170.     bset    #scndb,y:<flags
  1171.     jcc    putb3a                    ; reject frame if it is too short
  1172.     jsr    rejc
  1173.     rts
  1174.  
  1175. ; calculate the last CRC bit
  1176. putb3a    move            x:<rdata,x0
  1177.     move            #>@pow(2,-16),x1        ; shift to right 16 bits
  1178.     mpy    x0,x1,a
  1179.     crc    x:<rcrcrem
  1180.  
  1181. ; check that it is valid
  1182.     move            #>crcchk,x0
  1183.     eor    x0,a
  1184.     jne    putb3b                    ; reject frame if CRC failed
  1185.     jsr    endc
  1186.     rts
  1187. putb3b    jsr    rejc
  1188.     rts
  1189.  
  1190. ; abort detected
  1191. putb4    bset    #hunt,y:<flags
  1192.     jsr    rejc
  1193.     rts
  1194.  
  1195.  
  1196. ;****************************
  1197. ;*     Request timer        *
  1198. ;****************************
  1199. ; delay in x0 (in 1/baud s)
  1200. stimer    move            y:<timcnt,a
  1201.     add    x0,a        #>$00ffff,x0
  1202.     and    x0,a
  1203.     move            a1,y:<timval
  1204.     bset    #timer,y:<flags
  1205.     rts
  1206.  
  1207.  
  1208. ;****************************
  1209. ;*     Open codec driver    *
  1210. ;****************************
  1211. ; Start-up Crystal CS4215 Codec
  1212. ;   r7 - address of the modulo buffer (x: A/D, y: D/A)
  1213. ;   m7 - lenght of the modulo buffer
  1214. ;   x0 - samping rate:
  1215. ;    8    kHz   $000000
  1216. ;    9.6    kHz   $003800
  1217. ;      16    kHz   $000800
  1218. ;      27.42857 kHz   $001000
  1219. ;      32    kHz   $001800
  1220. ;      48    kHz   $003000
  1221. ;
  1222. ;
  1223. ; program SSI to handle Crystal's initial communication mode
  1224. opencd    movep            #$4f05,x:m_cra        ; 16-bit, 16 frames
  1225.     movep            #$3b3c,x:m_crb        ; generate SCLK and FS
  1226.  
  1227.     movep            #$01e3,x:m_pcc        ; TXD,RXD,SC2,SCK,SRD,STD
  1228.     movep            #$001c,x:m_pcddr        ; SCLK,SC0,SC1 as output
  1229.     movep            #$0000,x:m_pcd        ; PDN down (wake up Crystal)
  1230.  
  1231. ; send control blocks to the Crystal until we get valid responce from it
  1232.     move            y:<cryconf,a1        ; add sampling rate info to configuration block
  1233.     or    x0,a        #cryconf,r0
  1234.     move            a1,y:<cryconf
  1235.     move            #4-1,m0
  1236.  
  1237. wakeCry jsr    outblk                    ; send control info until CLB is low
  1238.     jset    #2+16,x:tmpblk+2,wakeCry
  1239.  
  1240. ; Crystal is configured, send final control block
  1241.     bset    #2+16,y:<cryconf+0            ; set CLB high
  1242.     do    #10,confok                ; at least two frames after CLB high
  1243.     jsr    outblk                    ; and ensure that at least 50 ms elapsed after leaving from PDN state
  1244.     nop
  1245. confok    move            #-1,m0
  1246.  
  1247. ; reset and reprogram SSI again because we will get clock and frame signals from Crystal
  1248.     movep            #$0003,x:m_pcc        ; SRD,STD
  1249.     movep            #$4305,x:m_cra        ; 16-bit, 4 frames
  1250.     movep            #$3b0c,x:m_crb        ; receive SCLK and FS
  1251.     movep            #$01e3,x:m_pcc        ; TXD,RXD,SC2,SCK,SRD,STD
  1252.  
  1253. ; then start data transfer and synchronize to it
  1254.     movep            #$0010,x:m_pcd        ; D/C high (switch Crystal to data mode)
  1255.  
  1256. waitsyn jclr    #m_tde,x:m_sr,waitsyn            ; wait for the frame sync
  1257.     jset    #m_tfs,x:m_sr,frmsync
  1258.     movep            x:m_rx,x:m_tsr
  1259.     jmp    waitsyn
  1260.  
  1261. frmsync do    #4-1,flshfrm                ; then get rid of the remaining data
  1262. _loop    jclr    #m_tde,x:m_sr,_loop
  1263.     movep            y:(r7)+,x:m_tx
  1264.     movep            x:m_rx,x:(r7)
  1265. flshfrm movep            #$7b0c,x:m_crb        ; enable transmit interrupts
  1266.  
  1267.     rts
  1268.  
  1269.  
  1270. ;****************************
  1271. ;*     Close codec driver   *
  1272. ;****************************
  1273. ; close SSI interface and set codec to power down mode
  1274. closecd movep            #$0003,x:m_pcc        ; TXD,RXD
  1275.     movep            #$001c,x:m_pcddr        ; SCLK,SC0,SC1 as output
  1276.     movep            #$0008,x:m_pcd        ; PDN up
  1277.  
  1278.     rts
  1279.  
  1280.  
  1281. ;****************************
  1282. ;*    Update output port    *
  1283. ;****************************
  1284. ; put lowest eight bits in x0 register to general purpose i/o-port
  1285. putio    ori    #$02,mr                 ; disable interrupts
  1286.     move            #>$0000ff,a1
  1287.     and    x0,a        #>$ffff00,x0
  1288.     move    a1,x1
  1289.  
  1290.     movep            x:m_pbd,a
  1291.     and    x0,a
  1292.     or    x1,a
  1293.     movep            a1,x:m_pbd
  1294.  
  1295.     andi    #$fc,mr
  1296.     rts
  1297.  
  1298. ; *** Persistence routines ***
  1299.  
  1300. ; state bits
  1301. xstart    equ    0
  1302. xstop    equ    1
  1303. xon    equ    2
  1304. xoff    equ    3
  1305. xwait    equ    4
  1306.  
  1307. ; kiss parameters
  1308. txdelay equ    1
  1309. P    equ    2
  1310. SlotTim equ    3
  1311. TXtail    equ    4
  1312. FullDup equ    5
  1313.  
  1314. kisspar dc    @cvi(50*baud/100.0)            ; txdelay
  1315.     dc    @cvi(63*baud/100.0)            ; P
  1316.     dc    @cvi(10*baud/100.0)            ; SlotTim
  1317.     dc    @cvi(1*baud/100.0)            ; TXtail
  1318.     dc    0                    ; FullDup
  1319. kisses    equ    *-kisspar
  1320.  
  1321. ;****************************
  1322. ;*   Carrier off routine    *
  1323. ;****************************
  1324. ; inform Leonid that there are no data transmissions ongoing
  1325. caroff    ori    #$02,mr
  1326.     nop
  1327.     nop
  1328.     nop
  1329.     bclr    #carrier,y:<flags
  1330.  
  1331.     jclr    #xwait,x:<pstate,_car1
  1332.  
  1333.     move            #(1<<xstart),a1        ; start xmitter
  1334.     move            a1,x:<pstate
  1335.  
  1336.     move            y:<xmitsub,r3        ; call XMIT ON
  1337.     ori    #$01,ccr
  1338.     jsr    (r3)
  1339.  
  1340.     move            p:kisspar+txdelay-1,a1  ; and set txdelay timer
  1341.     move            a1,y:<pertim
  1342. _car1    andi    #$fc,mr
  1343.     rts
  1344.  
  1345.  
  1346. ;****************************
  1347. ;*   Carrier off routine    *
  1348. ;****************************
  1349. ; inform Leonid that there are no data transmissions ongoing
  1350. caron    bset    #carrier,y:<flags
  1351.     rts
  1352.  
  1353.  
  1354. ; one KISS frame received
  1355. frmrec    jset    #xoff,x:<pstate,_frm1
  1356.     jset    #xstop,x:<pstate,_frm2
  1357.     rts
  1358.  
  1359. _frm1    jset    #carrier,y:<flags,_frm1a        ; if no carrier, then start xmitter
  1360.     move            y:<xmitsub,r3        ; call user's xmit on routine
  1361.     ori    #$01,ccr
  1362.     jsr    (r3)
  1363.  
  1364.     move            #(1<<xstart),a1        ; and change to XSTART state
  1365.     move            a1,x:<pstate
  1366.  
  1367.     move            p:kisspar+txdelay-1,a1  ; and set txdelay timer
  1368.     move            a1,y:<pertim
  1369.     rts
  1370.  
  1371. _frm1a    move            #(1<<xwait),a1        ; carrier, wait until it disappears
  1372.     move            a1,x:<pstate
  1373.     rts
  1374.  
  1375. _frm2    move            #(1<<xon),a1        ; curretly shutting down, but continue directly
  1376.     move            a1,x:<pstate
  1377.  
  1378.     bset    #givedat,y:<flags
  1379.     rts
  1380.  
  1381. ; trying to read empty buffer
  1382. rdempty ori    #$02,mr
  1383.     nop
  1384.     nop
  1385.     nop
  1386.     jclr    #xon,x:<pstate,_rde1
  1387.  
  1388.     move            #(1<<xstop),a1        ; stop transmitting
  1389.     move            a1,x:<pstate
  1390.  
  1391.     move            p:kisspar+TXtail-1,a1   ; and set txdelay timer
  1392.     move            a1,y:<pertim
  1393.  
  1394.     bclr    #givedat,y:<flags
  1395. _rde1    andi    #$fc,mr
  1396.     rts
  1397.  
  1398. ; 1/baud s timer ticks here
  1399. pertick move            y:<pertim,a1
  1400.     move            #>0,x0
  1401.     eor    x0,a        a1,r3
  1402.     jeq    _pert1
  1403.     move            (r3)-            ; check if timer elapsed
  1404.     move    r3,a1
  1405.     eor    x0,a        r3,y:<pertim
  1406.     jne    _pert1
  1407.     jset    #xstart,x:<pstate,_pert2
  1408.     jset    #xstop,x:<pstate,_pert3
  1409. _pert1    rts
  1410.  
  1411. _pert2    move            #(1<<xon),a1        ; start xmitting
  1412.     move            a1,x:<pstate
  1413.  
  1414.     bset    #givedat,y:<flags            ; start giving data to the application program
  1415.     rts
  1416.  
  1417. _pert3    move            #(1<<xoff),a1        ; stop xmitting
  1418.     move            a1,x:<pstate
  1419.  
  1420.     move            y:<xmitsub,r3        ; call user's xmit off
  1421.     andi    #$fe,ccr
  1422.     jsr    (r3)
  1423.     rts
  1424.  
  1425.  
  1426. ; read one word (updating CRC)
  1427. rdword    jsr    rdbyte                    ; MS byte
  1428.     move            #>@cvi(@pow(2,8-1)),x1
  1429.     mpy    x0,x1,a
  1430.     move            a0,y:<tmp
  1431.     jsr    rdbyte                    ; LS byte
  1432.     move            y:<tmp,a
  1433.     or    x0,a
  1434.     rts
  1435.  
  1436. ; wait 1s for the next character and update CRC calculation
  1437. rdbyte    move            #>@cvi(1.0*baud),x0     ; set timer (1s)
  1438.     jsr    stimer
  1439.     jsr    waitchr
  1440.     crcbyte                     ; calculate CRC of byte in x0, result in x:<crcrem
  1441.     rts
  1442.  
  1443.  
  1444. ; wait for (predetermined time) the next character
  1445. wchr    wait
  1446. waitchr jsr    getc                    ; wait for chr of timer
  1447.     jcc    chrfnd
  1448.     jset    #timer,y:<flags,wchr
  1449.  
  1450. sleep    move            #>@cvi(0.5*baud),x0     ; timer elapsed
  1451.     jsr    stimer                    ; error condition, blink cmd led
  1452. _sleep1 wait
  1453.     jset    #timer,y:<flags,_sleep1
  1454.     cmdled    chg
  1455.     jmp    sleep
  1456.  
  1457. chrfnd rts                        ; chr found
  1458.  
  1459.  
  1460. ; Output one 256 bit block (codec in the first time slot)
  1461. outblk    do    #4,outblk1                ; actual data transfer on the first slot only
  1462. _loop    jclr    #m_tde,x:m_sr,_loop
  1463.     movep            x:m_rx,x:(r0)
  1464.     movep            y:(r0)+,x:m_tx
  1465.  
  1466. outblk1 do    #16-4,outblk2                ; idling remainig slots
  1467. _loop    jclr    #m_tde,x:m_sr,_loop
  1468.     movep            a1,x:m_tsr
  1469.  
  1470. outblk2 rts
  1471.  
  1472.  
  1473. ; Calculate program load address (to a1) from the address in a1
  1474. ; returns Z if no program in a given slot
  1475. ldadr    rep    #4-1                    ; first calculate directory entry address (16*id+rom)
  1476.     lsl    a
  1477.     lsl    a        #>rom,x0
  1478.     add    x0,a
  1479.     move    a1,r1                    ; then fetch the load address
  1480.     jsr    romrdw
  1481.     rts
  1482.  
  1483.  
  1484.     romhdlr romrdb,romrdw,romload
  1485.  
  1486.  
  1487. ; serial buffers
  1488. inbuf    dsm    buflen
  1489. outbuf    dsm    buflen
  1490.  
  1491.  
  1492. ;****************************
  1493. ;*  CONTEX STORE FOR INTS   *
  1494. ;****************************
  1495.  
  1496.     org    l:$0000
  1497.  
  1498. scidata ds    2
  1499.  
  1500.  
  1501.     org    x:$0002
  1502.  
  1503. rhead    ds    1
  1504. rtail    ds    1
  1505.  
  1506. tmpblk    dsm    4
  1507.  
  1508. xhead    ds    1
  1509. xtail    ds    1
  1510. seqptr    ds    1
  1511. crcrem    ds    1
  1512.  
  1513. getkst    ds    1
  1514. rnhead    ds    1
  1515. xnhead    ds    1
  1516. kisscmd ds    1
  1517.  
  1518. rdata    ds    1                    ; current byte received
  1519. rflag    ds    1                    ; one bit counter
  1520. rbit    ds    1                    ; received bit counter
  1521. rcrcrem ds    1                    ; CRC remainder
  1522.  
  1523. pstate    ds    1                    ; xmit control module state
  1524.  
  1525.  
  1526.     org    y:$0002
  1527.  
  1528. flags    ds    1
  1529. tmp    ds    1
  1530.  
  1531. ; Crystal CS4215 configuration data
  1532. ; Stereo, 16-bit linear, XTAL1, 64 bit/frame, generate SCLK and FSYNC
  1533. cryconf dc    %0000000000000100<<8            ; Control Time Slot 1 & 2
  1534.     dc    %0001001000000000<<8            ; Control Time Slot 3 & 4
  1535.     dc    %0000000000000000<<8            ; Control Time Slot 5 & 6
  1536.     dc    %0000000000000000<<8            ; Control Time Slot 7 & 8
  1537.  
  1538. timcnt    ds    1
  1539. timval    ds    1
  1540. timchg    ds    1
  1541. mspace    ds    1
  1542. pgmptr    ds    1
  1543.  
  1544. khead    ds    1
  1545. kisssub ds    1
  1546.  
  1547. xstate    ds    1                    ; current xmitter state
  1548. xdata    ds    1                    ; current byte to be send
  1549. x5bit    ds    1                    ; one bit counter
  1550. xbit    ds    1                    ; send bits counter
  1551. xcrcrem ds    1                    ; CRC remainder
  1552.  
  1553. xmitsub ds    1                    ; xmit control module xmit routine address store
  1554. pertim    ds    1                    ; xmit control module timer
  1555.  
  1556.  
  1557.     end
  1558.